home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / c / jpl_c.zip / FORMAT.C < prev    next >
Text File  |  1986-05-18  |  5KB  |  193 lines

  1. /* 1.4  02-10-86                        (format.c)
  2. /************************************************************************
  3.  *            Robert C. Tausworthe                *
  4.  *            Jet Propulsion Laboratory            *
  5.  *            Pasadena, CA 91009        1986        *
  6.  ************************************************************************/
  7.  
  8. #include "defs.h"
  9. #include "ctype.h"
  10. #include "stdtyp.h"
  11. #include "stdio.h"
  12.  
  13. /************************************************************************/
  14.  
  15. format(xputc, fmt, args)    /* Formatted output of args using fmt;
  16.                    xputc() puts a character on the proper
  17.                    medium.  Return no. of chars printed
  18.                    or EOF if printing fails.        */
  19. /*----------------------------------------------------------------------*/
  20. FAST int (*xputc)();
  21. FAST STRING fmt;
  22. unsigned *args;
  23. {
  24.     FAST int c;
  25.     int cc, i, k, rjust, filler, precis, width;
  26.     long value;
  27.     STRING cp, ftoa(), ltoab(); 
  28.     char s[MAXLINE];
  29.     double dval;
  30.  
  31.     for (cc = 0; c = *fmt++; )
  32.     {    if (c ISNT '%')
  33.         {    cc++;
  34.             if ((*xputc)(c) < 0)
  35.                 return EOF;
  36.         }
  37.         else
  38.         {    rjust = TRUE;
  39.             filler = ' ';
  40.             precis = MAXLINE;
  41.             if ((c = *fmt++) IS '-')
  42.             {    rjust = FALSE;
  43.                 c = *fmt++;
  44.             }
  45.             if (c IS '0')
  46.             {    filler = '0';
  47.                 c = *fmt++;
  48.             }
  49. /*\p*/
  50.             if (c IS '*')
  51.             {    width = *args++;
  52.                 c = *fmt++;
  53.             }
  54.             else
  55.                 for (width = 0; isdigit(c) ; c = *fmt++)
  56.                 {    width *= 10;
  57.                     width += (c - '0');
  58.                 }
  59.             if (width > MAXLINE)
  60.                 width = MAXLINE;
  61.             if (c IS '.')
  62.                 if ((c = *fmt++) IS '*')
  63.                 {    precis = *args++;
  64.                     c = *fmt++;
  65.                 }
  66.                 else
  67.                     for (precis = 0; isdigit(c); c = *fmt++)
  68.                     {    precis *= 10;
  69.                         precis += (c - '0');
  70.                     }
  71.             switch(c)
  72.             {   case 'l':
  73.                 c = *fmt++;
  74.                 case 'D': case 'O': case 'X': case  'U':
  75.                 value = *((long *) args)++;
  76.                 break;
  77.                 case 'd':
  78.                 value = (int) *args++;
  79.                 break;
  80.                 case 'e': case 'f': case 'g':
  81.                 dval = *((double *) args)++;
  82.                 break;
  83.                 case 'o': case 'x': case 'u': case 's': case 'c':
  84.                 value = *args++;
  85.                 break;
  86.             }
  87.             if (rjust)
  88.                 k = (filler IS '0' AND width) ? -width : width;
  89.             else
  90.                 k = 0;
  91. /*\p*/
  92.             switch (TOLOWER(c))
  93.             {   case 'd':
  94.                 ltoab(s, value, k, 10);
  95.                 break;
  96.                 case 'o':
  97.                 ultoab(s, value, k, 8);
  98.                 break;
  99.                 case 'u':
  100.                 ultoab(s, value, k, 10);
  101.                 break;
  102.                 case 'x':
  103.                 ultoab(s, value, k, 16);
  104.                 break;
  105.                 case 'e':
  106.                 case 'f':
  107.                 case 'g':
  108.                 i = (precis IS MAXLINE) ? 6 : precis;
  109.                 lpadn(ftoa(s, dval, i, c), filler, k);
  110.                 precis = MAXLINE;
  111.                 break;
  112.                 case 's':
  113.                 if (precis > MAXLINE)
  114.                     precis = MAXLINE;
  115.                 strncpy(s, (STRING) (unsigned) value, precis);
  116.                 break;
  117.                 case 'c':
  118.                 c = value;
  119.                 default:
  120.                 *s = c;
  121.                 s[1] = NULL;
  122.             }
  123.             if ((i = strlen(s)) > precis)
  124.                 i = precis;
  125.             i = width - i;
  126.             if (rjust)
  127.                 for ( ; i-- > 0; cc++)    
  128.                     if ((*xputc)(filler) < 0)
  129.                         return EOF;
  130.  
  131.             for (k = 0, cp = s; *cp AND k < precis; ++k, cc++)
  132.                 if((*xputc)(*cp++) < 0)
  133.                     return EOF;
  134.  
  135.             for ( ; i-- > 0; cc++)
  136.                 if ((*xputc)(' ') < 0)
  137.                     return EOF;
  138.         }
  139.     }
  140.     return cc;
  141. }
  142. /*\p*********************************************************************/
  143.     LOCAL 
  144. lpadn(s, fill, n)    /* left-pad the numeric string s to width n using
  145.                the fill character.  Return s.        */
  146. /*----------------------------------------------------------------------*/
  147. FAST STRING s;
  148. FAST int n;
  149. {
  150.     FAST int k, L;
  151.  
  152.     n -= (L = strlen(s));
  153.     if (n > 0)
  154.     {    for (k = L; k >= 0; k--)    /* move everybody down    */
  155.              s[k + n] = s[k];
  156.         for (k = 0; k < n; k++)        /* and fill the holes.    */
  157.             s[k] = fill;
  158.         if (fill IS '0')
  159.         {    if (s[n] IS '-')
  160.                 *s = '-';    /* move the minus sign    */
  161.             s[n] = fill;        /* plug up the gap.    */
  162.         }
  163.     }
  164. }
  165.  
  166. /************************************************************************/
  167.     LOCAL VOID
  168. ultoab(s, n, w, b)    /* Convert unsigned long n to ascii string s, with
  169.                minimum width w, base b.  Return s.        */
  170. /*----------------------------------------------------------------------*/
  171. long n;
  172. STRING s;
  173. {
  174.     int low, hb;
  175.     STRING p, ltoab();
  176.  
  177.     if (n < 0)
  178.     {    low = (int) n & 1;    /* save the low bit of n.    */
  179.         hb = (b >> 1);        /* hb = half the base b.    */
  180.         n = LURSHIFT(n, 1);    /* n is now (n - low)/2).    */
  181.         low += ((int)(n % hb) << 1); /* the low digit base b    */
  182.         low += (low > 9) ? 'W' - 10 : '0';/* now ascii.    Note 'W'*/
  183.         n /= hb;        /* is 'a' - 10.  Reduce n,    */
  184.         w -= SGN(w);        /* reduce the width.        */
  185.     }
  186.     else
  187.         low = NULL;
  188.     p = s + strlen(ltoab(s, n, w, b));
  189.     *p++ = low;
  190.     *p = NULL;
  191.     return;
  192. }
  193.